﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Host
{
    public class ComponentsMapping2CallDescriptionComponents : IComponents
    {
        public ComponentsMapping2CallDescriptionComponents()
        {
        }

        private object GetAppropriateValue(ParameterInfo info)
        {
            if (info.HasDefaultValue)
            {
                return info.DefaultValue;
            }

            var item_type = info.ParameterType;
            return item_type.IsValueType ? Activator.CreateInstance(item_type) : null;
        }

        private object TryChangeData(Type type, Object obj)
        {
            return Convert.ChangeType(obj, type);
        }

        public override void OnEnter()
        {
            base.OnEnter();

            var calldescriptioncomponents = GetSameGropComponents<CallDescriptionComponents>("CallDescriptionComponents");
            TAssert.Assert(calldescriptioncomponents != null, "ComponentsMapping2CallDescriptionComponents Rely CallDescriptionComponents");

            foreach (var item in GetAllSameGropComponents())
            {
                if (item.Name == Name)
                    continue;

                var iattribute = item.GetType().GetCustomAttributes(typeof(IComponentsAttribute), true).FirstOrDefault() as IComponentsAttribute;
                if (iattribute != null && iattribute.Disable)
                    continue;

                foreach (var method in item.GetType().GetMethods())
                {
                    var attribute = method.GetCustomAttributes(typeof(IComponentsMethodAttribute), true).FirstOrDefault() as IComponentsMethodAttribute;
                    if (attribute == null)
                        continue;


                    string mapping_name = string.Format("{0}/{1}",
                                                        (iattribute != null && !string.IsNullOrEmpty(iattribute.MappingName)) ? iattribute.MappingName : item.Name,
                                                        !string.IsNullOrEmpty(attribute.MappingName) ? attribute.MappingName : method.Name);
                    calldescriptioncomponents.AddCallInfo(mapping_name, (data) =>
                    {
                        List<object> query_list = new List<object>();
                        foreach (var parameter_item in method.GetParameters())
                        {
                            var pName = parameter_item.Name;
                            var item_type = parameter_item.ParameterType;

                            // 从页面传入数据匹配最合适的数据
                            // todo bianchx：此处暂时支持简单数据类型，将来需要修改为可以支持复杂数据模型的绑定
                            while (true)
                            {
                                bool is_find = false;

                                if (data.ContainsKey(pName))
                                {
                                    query_list.Add(TryChangeData(item_type, data[pName]));
                                    is_find = true;
                                    break;
                                }

                                foreach (var item_data in data)
                                {
                                    if (item_data.Key.ToLower() == pName.ToLower())
                                    {
                                        query_list.Add(TryChangeData(item_type, item_data.Value));
                                        is_find = true;
                                        break;
                                    }
                                }
                                if (!is_find)
                                    query_list.Add(GetAppropriateValue(parameter_item));

                                break;
                            }
                        }

                        return method.Invoke(item, query_list.ToArray());
                    });


                    // todo bianchx:此处不应与HTTP做过多的耦合

                    //calldescriptioncomponents.AddCallInfo(mapping_name + "/Help", (data) =>
                    //{
                    //    string html_string = "";

                    //    html_string += "<!DOCTYPE html>";
                    //    html_string += "<html>";
                    //    html_string += "<head>";
                    //    html_string += "	<title>The Host Project</title>";
                    //    html_string += "</head>";
                    //    html_string += "<body>";
                    //    html_string += "<h1>" + mapping_name + "</h1>";
                    //    html_string += "<ul>";
                    //    foreach (var parameter_item in method.GetParameters())
                    //    {
                    //        html_string += string.Format("	<li>{0}\t{1}\t[{2}]</li>",
                    //                                     parameter_item.Name, parameter_item.ParameterType.ToString(),
                    //                                     parameter_item.HasDefaultValue ? parameter_item.DefaultValue : string.Empty);
                    //    }
                    //    html_string += "</ul>";
                    //    html_string += "</body>";
                    //    html_string += "</html>";

                    //    return html_string;
                    //});
                }
            }
        }
    }
}
